package com.fish.common.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 验证码服务
 *
 * @author fish
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VerificationCodeService {

    private final StringRedisTemplate stringRedisTemplate;
    private final EmailService emailService;

    private static final String CODE_PREFIX = "verification_code:";
    private static final int CODE_LENGTH = 6;
    private static final long CODE_EXPIRE_TIME = 5; // 分钟

    /**
     * 生成随机验证码
     */
    private String generateCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < CODE_LENGTH; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }

    /**
     * 发送邮箱验证码
     */
    public void sendEmailCode(String email) {
        String code = generateCode();
        String key = CODE_PREFIX + email;
        
        // 检查是否在60秒内发送过验证码
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(key + ":last_send"))) {
            throw new RuntimeException("发送过于频繁，请稍后再试");
        }
        
        // 保存验证码到Redis，5分钟过期
        stringRedisTemplate.opsForValue().set(key, code, CODE_EXPIRE_TIME, TimeUnit.MINUTES);
        // 设置60秒内不能重复发送
        stringRedisTemplate.opsForValue().set(key + ":last_send", "1", 60, TimeUnit.SECONDS);
        
        // 发送邮件
        emailService.sendVerificationCode(email, code);
        log.info("发送邮箱验证码成功，邮箱：{}，验证码：{}", email, code);
    }

    /**
     * 验证邮箱验证码
     */
    public boolean verifyEmailCode(String email, String code) {
        String key = CODE_PREFIX + email;
        log.info("验证邮箱验证码，邮箱：{}，输入验证码：{}", email, code);
        
        String savedCode = stringRedisTemplate.opsForValue().get(key);
        log.info("Redis中存储的验证码：{}", savedCode);
        
        if (savedCode == null) {
            log.warn("验证码不存在或已过期，邮箱：{}", email);
            return false;
        }
        
        // 去除可能的空格并比较
        boolean isValid = savedCode.trim().equals(code.trim());
        log.info("验证码比对结果：{}", isValid ? "成功" : "失败");
        
        if (isValid) {
            // 验证成功后删除验证码
            stringRedisTemplate.delete(key);
            log.info("验证成功，已删除验证码");
        } else {
            log.warn("验证码不匹配，期望：[{}]，实际：[{}]", savedCode, code);
        }
        
        return isValid;
    }

    /**
     * 清除验证码
     */
    public void clearCode(String email) {
        String key = CODE_PREFIX + email;
        stringRedisTemplate.delete(key);
    }
}
